import * as lodash from "lodash";

/**
 * 将 key 对应的 值取出,
 * @param key key
 * @param o 被搜索的对象
 * @param def 默认值 在没有找到时使用他
 */
export function searchObject(key: any, o: any, def?: any): any {
  return lodash.get(o, key, def);
}

/***
 * 判断对象是否为空
 * - 数值为 0
 * - 字符串长度为 0
 * - 其他使用 lodash 比较
 * @param o
 */
export function isEmpty(o: any): boolean {
  if (o === null || o === undefined) {
    return true;
  }

  switch (typeof o) {
    case "number":
      return o === 0;
    case "string":
      return o.length === 0;
    case "undefined":
      return true;
    default:
      return lodash.isEmpty(o);
  }
}

export function chunk<T>(array: T | T[] | ArrayLike<T>, size: number): any {
  switch (typeof array) {
    case "string": {
      const packs = Math.ceil(array.length / size);
      const msgs: string[] = [];
      for (let i = 0; i < packs; i++) {
        msgs.push(array.slice(i * size, i * size + size));
      }
      return msgs;
    }
    default:
      return lodash.chunk(array as ArrayLike<T>, size);
  }
}

type stepFunction = (i: number, before: number, data: number[]) => number;
interface rangeOptions {
  length?: number; // 数组长度
  start?: number; // 起始值
  end?: number; // 结束值
  step?: number | stepFunction; // 间隔值
}

/**
 * 生成序数组
 * @param options
 */
export function arrayRanges(options: rangeOptions): number[] {
  const { length = undefined, start = 0, end = undefined, step = 1 } = options;
  const out: number[] = [];
  let data = start;

  // 数组中的软件
  out.push(start);

  // eslint-disable-next-line no-constant-condition
  while (true) {
    // 根据不同的 step 类型计算下一个点
    switch (typeof step) {
      case "number": {
        data = data + step;
        break;
      }
      case "function": {
        data = data + step(out.length, data, out);
        break;
      }
    }

    // 判断是否超过末尾
    if (end !== undefined && data > end) {
      break;
    }

    if (length !== undefined && out.length >= length) {
      break;
    }

    out.push(data);
  }

  return out;
}
